package com.bvbot.core.bot;

import static com.bvbot.core.Logger.log;

import com.bvbot.core.VolatilityLauncher;
import com.bvbot.core.order.SecuritySeller;
import com.bvbot.core.session.BalanceResponse;
import com.bvbot.core.session.BvSession;
import com.bvbot.core.session.BvSessionException;

public class SecurityLimitBot extends AbstractBot<SecurityLimitConfig> {

	public static final long LIMIT_BOT_PAUSE_IN_MILLIS = 60000L;// 1 minute

	private Float allTimeMaxSecurityPriceValue;

	public SecurityLimitBot(SecurityLimitConfig conf) {
		super(conf);
	}

	@Override
	public Decision computeDecision() {
		Decision result = Decision.NOTHING;
		Prices p = getHistory().getCurrentPrice();
		if (p != null) {
			Float priceValue = null;
			if (getConfig().isGold()) {
				priceValue = p.getGoldWorldValue();
			} else {
				priceValue = p.getSilverWorldValue();
			}
			if (allTimeMaxSecurityPriceValue == null
					|| allTimeMaxSecurityPriceValue < priceValue) {
				allTimeMaxSecurityPriceValue = priceValue;
				log("Setting all time security price value at "
						+ allTimeMaxSecurityPriceValue);
			}
			if (priceValue != null) {
				Float sellLimit = allTimeMaxSecurityPriceValue
						* getConfig().getSellLimitRatio();
				log("Current price is " + priceValue + ". Sell limit is "
						+ sellLimit);
				if (priceValue < sellLimit) {
					log("Current price is below sell limit. Decision to SELL");
					result = Decision.SELL;
				}
			}

		}
		return result;
	}

	@Override
	protected void reinitState() {
	}

	@Override
	protected void applyDecision(Decision decision) {
		switch (decision) {
		case SELL:
			if (getConfig().isGold()) {
				sellGold();
			} else {
				sellSilver();
			}
			int grams = getCurrentGrams();
			boolean terminate = (grams == 0);
			if (terminate) {
				log("No more grams are available. Bot can die.");
				askForTermination();
			}

		default:
			break;
		}

	}

	private int getCurrentGrams() {
		int grams = -1;
		BvSession sess = new BvSession();
		try {
			sess.start();
			BalanceResponse br = sess.getBalance();
			if (br != null) {
				if (getConfig().isGold()) {
					grams = br.getGoldGrams();
				} else {
					grams = br.getSilverGrams();
				}
			}
		} catch (BvSessionException e) {
			log("Exception : " + e.getMessage(), e);
		}
		return grams;
	}

	@Override
	protected void sellGold() {
		log("Sale of gold");
		SecuritySeller seller = new SecuritySeller(true);
		seller.sellRatio(1);
	}

	@Override
	protected void sellSilver() {
		log("Sale of silver");
		SecuritySeller seller = new SecuritySeller(false);
		seller.sellRatio(1);
	}

	public static void main(String[] args) {
		Float sellLimitRatio = VolatilityLauncher.getMandatoryFloatParam(args,
				"sellLimitRatio");
		String security = VolatilityLauncher.getMandatoryStringParam(args,
				"security");
		SecurityLimitConfig conf = new SecurityLimitConfig();
		if (security.equals("gold")) {
			conf.setGold(true);
		} else {
			conf.setGold(false);
		}
		conf.setSellLimitRatio(sellLimitRatio);
		SecurityLimitBot bot = new SecurityLimitBot(conf);
		bot.start();
	}

	@Override
	public long getPauseInMillis() {
		return LIMIT_BOT_PAUSE_IN_MILLIS;
	}

	@Override
	protected String getNameForThread() {
		return "SecurityLimitBot on "
				+ (getConfig().isGold() ? "gold" : "silver");
	}

}
